#ifndef _SQLite3_hpp_
#define _SQLite3_hpp_

#include <sqlite3.h>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include "except.hpp"
namespace sqlite
{
using namespace std;
//class Database;

template <class T> std::string toString(const T& a)
{
    std::ostringstream ost;
    ost << a;
    return ost.str();
}
template<typename T>T fromString( const std::string& s)
// string conversion from string to typename T with a flag
// the represents success or failure.
//
// e.g: int d = FromString<int>( s );
//
////////////////////////////////////////////////////////////////////////////
//
{
    std::istringstream is(s);
    T t;
    is >> t;
    return t;
}

/** SQL data row wrapper. */
class Record : public std::vector<std::string>
{
public:
    Record() : std::vector<std::string>() {}
    /** defined for compatibility with Persistent */
    // Record(const SQLite3 & db, const Record& r ) { *this = r;}
};

/** shortcut */
typedef std::vector<Record> Records;

class SQLite3
{
    sqlite3* db;
    mutable bool transaction;
protected:
    void throwError(int status) const;
public:
    /** SQLite3 - result */
    class Result
    {
    public:
        std::vector<Record> recs;
        Record flds;
        Result() {}
        virtual size_t fieldNum() const;
        virtual Record fields() const;
        virtual size_t recordNum() const;
        virtual Records records() const;
        const Records& recordsRef() const;
    };
    /** SQLite3 - cursor */
    class Cursor
    {
        sqlite3 * db;
        sqlite3_stmt * stmt;
        const SQLite3& owner;
    public:
        Cursor(sqlite3 * db, sqlite3_stmt * s, const SQLite3& owner);
        virtual Record fetchOne();
        virtual ~Cursor();
    };

    SQLite3() {}
    SQLite3(const string database);
    void open(const string database);
    //替换SQL字符串中的特殊字符，包括\'等
    std::string escapeSQL(const string);
    virtual bool supportsSequences() const;
    virtual string getInsertID() const;
    virtual void begin() const;
    virtual void commit() const;
    virtual void rollback() const;
    int command(const string query)const;
    bool tableExists(const std::string) const;
    SQLite3::Result* execute(const string query) const;
    SQLite3::Cursor* cursor(const string query) const;
    static const char*  version()
    {
        return SQLITE_VERSION;
    }
    virtual ~SQLite3();
};
}
#endif
